package mylibrary.socket.proxy.sample;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class SocketThread extends Thread {

	private Socket socketIn;
	private InputStream isIn;
	private OutputStream osIn;
	
	private Socket socketOut;
	private InputStream isOut;
	private OutputStream osOut;
	
	public SocketThread(Socket socket) {
		socketIn = socket;
	}
	
	private byte[] buffer = new byte[4096];

	private static final byte[] VER = { 0x5, 0x0 };
	private static final byte[] CONNECT_OK = { 0x5, 0x0, 0x0, 0x1, 0, 0, 0, 0, 0, 0 };  
	
	public void run() {
		
		try {
			System.out.println("\n\nA client connect " + socketIn.getInetAddress() + ":" + socketIn.getPort());
			
			isIn = socketIn.getInputStream();
			osIn = socketIn.getOutputStream();
			int len = isIn.read(buffer);
			
			osIn.write(VER);
			osIn.flush();
			len = isIn.read(buffer);
			

			String host = findHost(buffer, 4, 7);
			int port = findPort(buffer, 8, 9);
			System.out.println("host=" + host + ",port=" + port);
			
			socketOut = new Socket(host, port);
			isOut = socketOut.getInputStream();
			osOut = socketOut.getOutputStream();
			
			for(int i=4; i<=9; i++) {
				CONNECT_OK[i] = buffer[i];
			}
			osIn.write(CONNECT_OK);
			osIn.flush();
			
			SocketThreadOutput out = new SocketThreadOutput(isIn, osOut);
			out.start();
			
			SocketThreadInput in = new SocketThreadInput(isOut, osIn);
			in.start();
			
			out.join();
			in.join();
			
		} catch (Exception e) {
			
		}
	}
	
	public static String findHost(byte[] bArray, int begin, int end) {
		StringBuffer sb = new StringBuffer();
		for(int i=begin; i<=end; i++) {
			sb.append(Integer.toString(0xFF & bArray[i]));  
            sb.append(".");  
		}
		sb.deleteCharAt(sb.length() - 1);
		return sb.toString();
	}
	
	public static int findPort(byte[] bArray, int begin, int end) {
		
		int port = 0;
		for(int i=begin; i<=end; i++) {
			port <<=16;
			port += bArray[i];
		}
		return port;
	}
}
